#include "unione_lite.h"
#include "DrvUART010.h"
#include "interrupt.h"
#include "mailbox.h"


/**********************************************************************
irq_type:
     bit2: bit1: bit0 --- send:recv:err
***********************************************************************/

int mailbox_init(void (*mailbox_isr)(void *args), int rx_threshold, int tx_threshold, void *args)
{
	u32 value;
	u32 sema_reg;	
	u32 mailbox_reg;

	mailbox_reg = MAILBOX_INT_STATUS(MAILBOX_616);
	value = READ(mailbox_reg);
	WRITE(mailbox_reg,value);//clear irq;

	sema_reg = MAILBOX_RX_THRESHOLD(MAILBOX_616);
	value = rx_threshold;  //rx threshold 8
	WRITE(sema_reg, value);

	sema_reg = MAILBOX_TX_THRESHOLD(MAILBOX_616);
	value = tx_threshold;  //tx threshold 8
	WRITE(sema_reg, value);

	sema_reg = MAILBOX_CTRL(MAILBOX_616);
	value = 0x03;  //clear tx fifo and tx fifo
	WRITE(sema_reg, value);

	sema_reg = MAILBOX_INT_ENABLE(MAILBOX_616);

	value = 0x06;  //receive interrupt and error interrupt
	WRITE(sema_reg, value);

	fLib_CloseInt(MAILBOX_INT_NUMBER);
	if (!fLib_ConnectInt(MAILBOX_INT_NUMBER, (PrVoid)mailbox_isr))
		return 1;

	fLib_SetIntTrig(MAILBOX_INT_NUMBER, 0, 0);//level,high
	fLib_EnableInt(MAILBOX_INT_NUMBER);
	return 0;
}


int mailbox_sema_lock(mailbox_lock lock)
{
    u32 sema_reg = MAILBOX_SEMA(lock);
    int locked = 0;
	int block = 1;
	u32 loop = 0x7fffffff;
    
    WRITE(sema_reg, SEMA_LOCK_REQ_BIT);
    do{
        locked = !!(READ(sema_reg) & SEMA_LOCK_STATUS_BIT);
    }while(!locked && (block || loop--));

    return locked;
}

void mailbox_sema_unlock(mailbox_lock lock)
{
    u32 sema_reg = MAILBOX_SEMA(lock);
    WRITE(sema_reg, SEMA_LOCK_CLR_BIT);
}

int mailbox_sema_is_lock(mailbox_lock lock)
{
    int locked = 0;
    u32 sema_reg = MAILBOX_SEMA(lock);
    locked = !!(READ(sema_reg) & SEMA_LOCK_STATUS_BIT);
	return locked;
}


int mailbox_send_msg(mailbox_message *message)
{
	int value;
	u32 mailbox_reg = MAILBOX_STATUS(MAILBOX_616);
	value = READ(mailbox_reg);
	value = value & 0x04;
	if(0 == value) {
		//the send fifo is greater than SIT
		return -1;
	}
	mailbox_reg = MAILBOX_WRDATA(MAILBOX_616);
	WRITE(mailbox_reg,message->sequenceId);
	WRITE(mailbox_reg,message->taskId);
	WRITE(mailbox_reg,message->size);
	WRITE(mailbox_reg,message->data[0]);
	WRITE(mailbox_reg,message->data[1]);
	WRITE(mailbox_reg,message->data[2]);
	WRITE(mailbox_reg,message->data[3]);
	WRITE(mailbox_reg,message->data[4]);
	return 0;
}

